package reflex;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import dao.DBUtil;

public class SqlBase<T> {
	private Class<T> entity;
	private String tablename;
	private Connection conn;

	@SuppressWarnings("unchecked")
	public SqlBase() {
		ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
		entity = (Class<T>) type.getActualTypeArguments()[0];
		tablename = entity.getSimpleName();
		conn = DBUtil.getCon();

	}

	public void insert(T o) {
		StringBuffer sql = new StringBuffer("insert into " + tablename + "(");
		Field[] fd = entity.getDeclaredFields();
		for (int i = 0; i < fd.length; i++) {
			sql.append(fd[i].getName());
			if (i < fd.length - 1)
				sql.append(",");
			else
				sql.append(") values(");
		}
		for (int i = 0; i < fd.length; i++) {
			sql.append("?");
			if (i < fd.length - 1)
				sql.append(",");
			else
				sql.append(")");
		}
		System.out.println(sql.toString());
		try {
			PreparedStatement pstm = conn.prepareStatement(sql.toString());
			for (int i = 0; i < fd.length; i++) {
				fd[i].setAccessible(true);
				Object val = fd[i].get(o);
				pstm.setObject(i + 1, val);
			}
			pstm.executeUpdate();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void delect(Integer id) {
		// delete from tablename where pk=id;
		Field[] fd = entity.getDeclaredFields();
		StringBuffer sql = new StringBuffer("delete from " + tablename + " where " + fd[0].getName() + "=" + id);
		System.out.println(sql);

		try {

			Statement stm = conn.createStatement();
			stm.executeQuery(sql.toString());
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public void update(Object o) {
		// update tableame set name=?,sex=? where Pk=?;
		Field[] fd = entity.getDeclaredFields();
		StringBuffer sql = new StringBuffer("update " + tablename + " set ");
		for (int i = 1; i < fd.length; i++) {
			sql.append(fd[i].getName() + "=?");
			if (i < fd.length - 1) {
				sql.append(",");

			} else {
				sql.append(" where " + fd[0].getName() + "=?");
			}

		}
		System.out.println(sql.toString());
		try {
			PreparedStatement pre = conn.prepareStatement(sql.toString());

			for (int i = 1; i < fd.length; i++) {
				fd[i].setAccessible(true);
				Object val = fd[i].get(o);
				pre.setObject(i, val);

			}
			System.out.println("::::::");
			fd[0].setAccessible(true);
			Object val = fd[0].get(o);
			pre.setObject(fd.length, val);
			System.out.println("fasd");
			pre.executeUpdate();

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public T getOne(T o) {
		// select * from tablename where pk=id;
		Field[] fd = entity.getDeclaredFields();

		StringBuffer sql = new StringBuffer("select * from " + tablename + " where " + fd[0].getName() + "=?");
		System.out.println(sql.toString());

		try {
			PreparedStatement pre = conn.prepareStatement(sql.toString());
			fd[0].setAccessible(true);//
			Object val = fd[0].get(o);
			pre.setObject(1, val);
			ResultSet res = pre.executeQuery();
			res.next();

			T one = entity.newInstance();
			for (int i = 0; i < fd.length; i++) {
				fd[i].setAccessible(true);
				Object ob = res.getObject(i + 1);
				if (fd[i].getType().getSimpleName().equals("Integer")) {
					BigDecimal bd = (BigDecimal) ob;
					ob = bd.intValue();

				}
				fd[i].set(one, ob);
			}

			return one;

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();

		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();

		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();

		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;

	}

	public List<T> getAll() {
		List<T> list = new ArrayList<>();
		Field[] fd = entity.getDeclaredFields();
		StringBuffer sql = new StringBuffer("select * from " + tablename);
		System.out.println(sql);
		try {
			Statement sta = conn.createStatement();
			ResultSet res = sta.executeQuery(sql.toString());
			while (res.next()) {
				T one = entity.newInstance();
				for (int i = 0; i < fd.length; i++) {
					fd[i].setAccessible(true);
					Object val = res.getObject(i + 1);
					if (fd[i].getType().getSimpleName().equals("Integer")) {
						BigDecimal bd = (BigDecimal) val;
						val = bd.intValue();
					}
					fd[i].set(one, val);

				}
				list.add(one);

			}
			return list;

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;

	}

}
